﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Common.ECS;
using System.Reflection;
using System.Collections;

public class ConditionNodeHandler : INodeHandler<BehaviorEntity>
{

    public BehaviorNodeState ExcuteNode(BehaviorEntity entity, NodeData node)
    {
        LeafNodeData data = (LeafNodeData)node;
        ConditionTaskData taskData = (ConditionTaskData)data.TaskArgs;
        if (entity.Components.ContainsKey(taskData.LeftComponentType))
        {
            string[] contents = taskData.LeftArgs.Split('.');
            var left = ReflectUtils.GetTargetPropertyValue(entity.Components[taskData.LeftComponentType], contents);
            if (taskData.RightArgsType != ConstType.None)
            {
                switch (taskData.RightArgsType)
                {
                    case ConstType.String:
                        return CompareValue((string)left, taskData.Operator, (string)taskData.RightArgs);
                    case ConstType.Int:
                        return CompareValue((int)left, taskData.Operator, (int)taskData.RightArgs);
                    case ConstType.Float:
                        return CompareValue((float)left, taskData.Operator, (float)taskData.RightArgs);
                    default:
                        break;
                }
            }
            else if (entity.Components.ContainsKey(taskData.RightComponentType))
            {
                FieldInfo[] fields = entity.Components[taskData.RightComponentType].GetType().GetFields();
                for (int j = 0; j < fields.Length; j++)
                {
                    if (fields[j].Name == taskData.RightArgs.ToString())
                    {
                        var right = fields[j].GetValue(entity.Components[taskData.LeftComponentType]);
                        return CompareValue((IComparable)left, taskData.Operator, (IComparable)right);
                    }
                }
            }
        }

        return BehaviorNodeState.Failure;
    }

    public void ResetNode(NodeData node)
    {
        LeafNodeData data = (LeafNodeData)node;
        node.CurNodeState = BehaviorNodeState.Running;
    }

    public BehaviorNodeState CompareValue<T>(T left,OperatorType operater,T right) where T: IComparable
    {
        int result = left.CompareTo(right);
        switch (operater)
        {
            case OperatorType.BiggerThan:
                if (result > 0)
                {
                    return BehaviorNodeState.Success;
                }
                else
                {
                    return BehaviorNodeState.Failure;
                }
            case OperatorType.LessThan:
                if (result < 0)
                {
                    return BehaviorNodeState.Success;
                }
                else
                {
                    return BehaviorNodeState.Failure;
                }
            case OperatorType.Equal:
                if (result == 0)
                {
                    return BehaviorNodeState.Success;
                }
                else
                {
                    return BehaviorNodeState.Failure;
                }
            default:
                return BehaviorNodeState.Failure;
        }
    }
}